const vscode = require('vscode');
const path = require('path');
const fs = require('fs');
const util = require('../util');

/**
 * ctx.(service|util).xxx 跳转增强
 * @param {*} document 
 * @param {*} position 
 * @param {*} token 
 */
function provideDefinition(document, position, token) {
    const fileName    = document.fileName;
    const workDir     = path.dirname(fileName);
    const word        = document.getText(document.getWordRangeAtPosition(position));
    const line        = document.lineAt(position);
    const projectPath = util.getProjectPath(document);

    util.log('====== provideDefinition 查找 ===========');
    util.log('fileName: ' + fileName);
    util.log('workDir: ' + workDir);
    util.log('word: ' + word);
    util.log('line: ' + line.text);
    util.log('projectPath: ' + projectPath);

    // 匹配 this.proxy.xxx(.xxx)，这里的匹配比较简单粗暴
    const result = /(^|=| )(ctx|this)\.((service|util)\.[\w.]+)($|\(| )/g.exec(line.text);
    if (!result || !result[3]) return;
    const temp = result[3].split('.');
    let filePath = `${projectPath}/app/${temp.join('/')}.js`;
    if (fs.existsSync(filePath)) {
        return new vscode.Location(vscode.Uri.file(filePath), new vscode.Position(0, 0));
    }
    const methodName = temp.pop();
    filePath = `${projectPath}/app/${temp.join('/')}.js`;
    if (!fs.existsSync(filePath)) {
        // ctx.service.hsf.finInsurance.xxx 需要处理成 ctx.service.hsf.fin-insurance.xxx
        console.warn('File not found: ' + filePath);
        if (temp[1] === 'hsf') {
            temp[2] = util.toUnderline(temp[2], '-');
            filePath = `${projectPath}/app/${temp.join('/')}.js`;
            if (!fs.existsSync(filePath)) {
                return;
            }
        } else {
            return;
        }
    }
    const pos = util.findStrInFile(filePath, new RegExp(` ${methodName}(\\(| =)`));
    return new vscode.Location(vscode.Uri.file(filePath), new vscode.Position(pos.row, pos.col));
}

module.exports = function(context) {
    // 注册如何实现跳转到定义
    context.subscriptions.push(vscode.languages.registerDefinitionProvider(['javascript', 'javascriptreact'], {
        provideDefinition
    }));
};